package battle

import (
	"server/game/cache"
	"server/game/model"
	"server/share/config"

	"github.com/hwcer/cosgo/random"
	"github.com/hwcer/cosgo/registry"
	"github.com/hwcer/yyds"
	"github.com/hwcer/yyds/context"
	"github.com/hwcer/yyds/errors"
)

func init() {
	Register(&newStage{})
}

/**
 * @name newStage
 * 新战斗系统
 */

type newStage struct{}

func (this *newStage) Caller(node *registry.Node, handle *context.Context) interface{} {
	f := node.Method().(func(*newStage, *context.Context) interface{})
	return f(this, handle)
}

/**
 * @name killMonster
 * @param json data 击杀数据
 * 击杀数量  ，主要刷新好友BOSS
 */
func (this *newStage) KillMonster(c *context.Context) interface{} {
	args := struct {
		Data map[string]int32 `json:"data"`
	}{
		Data: map[string]int32{},
	}

	if err := c.Bind(&args); err != nil {
		return err
	}
	data := args.Data
	if len(data) == 0 {
		return errors.ErrArgEmpty
	}
	roleDoc := cache.GetRole(c.Player.Updater)
	roleData := roleDoc.All()
	itemColl := cache.GetItems(c.Player.Updater)
	num := int32(0)
	for k, v := range data {
		unit := itemColl.Get(k)
		if unit == nil {
			return errors.Errorf(0, "unit not found:%v", k)
		}
		if !yyds.Config.Is(unit.IID, config.ITypeUnit) {
			return errors.Errorf(0, "not unit:%v", k)
		}
		num += v
		itemColl.SetAttach(unit.OID, model.AttachUnitKill, unit.Attach.GetInt32(model.AttachUnitKill)+v)
	}
	c.Player.Emit(config.Data.Events.KillMonsterNum, num)

	if roleData.FWbossID != 0 {
		return true
	}
	starConfig := config.Data.MeteorGroup
	if starConfig == nil {
		return errors.ErrConfigEmpty
	}
	meteorID := int32(0)
	//for _, d := range starConfig {
	//	if d.Type == 2 && d.EffectStage <= roleData.BattlePoint && d.MeteorID > meteorID {
	//		meteorID = d.MeteorID
	//	}
	//}
	if meteorID == 0 {
		return nil
	}
	// //在此进行是否刷新出好友boss的判断
	// //根据fWbossX计算刷新概率，如果 (fwbossX-addRateNum) 大于0 ,rate = meteorRate+(fwbossX-addRateNum)*addRate
	// //否则 rate = meteorRate
	meteorConfig := config.Data.FriendBossMeteor[meteorID]
	if meteorConfig == nil {
		return errors.ErrConfigEmpty
	}
	fWbossX := roleData.FWbossX + num
	rate := meteorConfig.MeteorRate
	if n := fWbossX - meteorConfig.AddRateNum; n > 0 {
		rate += meteorConfig.AddRate * n
	}
	if !random.Probability(rate) {
		roleDoc.Set("FWbossX", fWbossX)
	} else {
		roleDoc.Set("FWbossX", 0)
		roleDoc.Set("FWbossID", meteorID)
	}

	return nil
}

/**
 * @name startBattle
 * @param int id 关卡ID
 * @tip 主线通关记录在role.stage里
 * 创建战斗
 */
func (this *newStage) StartBattle(c *context.Context) interface{} {
	id := c.GetInt32("id")
	if id <= 0 {
		return errors.ErrArgEmpty
	}
	stageConfig := config.Data.Stage[id]
	if stageConfig == nil {
		return errors.ErrConfigEmpty
	}
	if stageConfig.BeforeStage > 0 {
		beforeStageConfig := config.Data.Stage[stageConfig.BeforeStage]
		if beforeStageConfig == nil {
			return errors.ErrConfigEmpty
		}

		roleDoc := cache.GetRole(c.Player.Updater)
		roleData := roleDoc.All()
		if v := roleData.NewStage[beforeStageConfig.Type]; v < stageConfig.BeforeStage {
			return c.Error("BeforeStage Limit")
		}
	}

	mw := &Middleware{}
	mw.Create(c.Player, MiddlewareTypeNewStage, id, nil)
	return 0
}

/**
 * @name endBattle
 * @param int id 关卡ID
 * 结束战斗
 */

func (this *newStage) EndBattle(c *context.Context) interface{} {
	id := c.GetInt32("id")
	if id <= 0 {
		return errors.ErrArgEmpty
	}
	stageConfig := config.Data.Stage[id]
	if stageConfig == nil {
		return errors.ErrConfigEmpty
	}

	mw := &Middleware{}
	if !mw.Verify(c.Player, MiddlewareTypeNewStage, id) {
		return c.Error("battle error")
	}

	roleDoc := cache.GetRole(c.Player.Updater)
	roleData := roleDoc.All()
	if id > roleData.NewStage[stageConfig.Type] {
		s := map[int32]int32{}
		for k, v := range roleData.NewStage {
			s[k] = v
		}
		s[stageConfig.Type] = id
		roleDoc.Set("NewStage", s)
		//if len(roleData.NewStage) == 0 {
		//	roleDoc.Set("NewStage", map[int32]int32{stageConfig.Type: id})
		//} else {
		//	roleDoc.Set("NewStage", id, stageConfig.Type)
		//}

		c.Player.Add(stageConfig.FirstReward, 1)
		c.Player.AddItems(stageConfig.ItemDrop)
	}
	for _, k := range stageConfig.Reward {
		if k > 0 {
			c.Player.Add(k, 1)
		}
	}
	c.Player.Sub(stageConfig.Ticket, 1)
	for _, k := range stageConfig.Events {
		c.Player.Emit(k, 1)
	}
	return map[string]interface{}{"win": true}
}

/**
 * @name swapStage
 * @param int id 关卡ID
 * @param int num 扫荡次数
 * 扫荡关卡
 */

func (this *newStage) SwapStage(c *context.Context) interface{} {
	id := c.GetInt32("id")
	num := c.GetInt32("num")
	if id <= 0 || num <= 0 {
		return errors.ErrArgEmpty
	}
	stageConfig := config.Data.Stage[id]
	if stageConfig == nil {
		return errors.ErrConfigEmpty
	}
	roleDoc := cache.GetRole(c.Player.Updater)
	roleData := roleDoc.All()
	if v := roleData.NewStage[stageConfig.Type]; id > v {
		return c.Error("NewStage Limit")
	}
	for _, k := range stageConfig.Reward {
		if k > 0 {
			c.Player.Add(k, num)
		}
	}
	c.Player.Sub(stageConfig.Ticket, num)
	moppingTicket := config.Data.Base["moppingTicket"]
	if moppingTicket == nil || moppingTicket.Val == 0 {
		return c.Error("base.moppingTicket empty")
	}
	c.Player.Sub(moppingTicket.Val, num)
	return nil
}
